package com.esil.project.util;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;


/**Classe permettant la recherche des images proches de celles sélectionnées
 * @author sophie
 */

public class RechercheDistance {
	
	ArrayList<String> ListeUrl;
	Connection connection;
	ArrayList<String> URLimages;
	ArrayList<String> jaimepas;
	float distjaime[];
	float distjaimepas[];
	
	
	/**Constructeur par défaut
	 * @param jaime
	 * @param jpas
	 */
	public RechercheDistance(String jaime[],String jpas[]){
		ListeUrl=new ArrayList<String>();
		jaimepas=new ArrayList<String>();
		for(int i=0;i<jaime.length;i++){
			if(!jaime[i].isEmpty()){
				ListeUrl .add("WebContent/"+jaime[i]);
			}
		}
		for(int i=0;i<jpas.length;i++){
			if(!jpas[i].isEmpty()){
				jaimepas .add("WebContent/"+jpas[i]);
			}
		}
		//calcul du nombre d'images dans la BDD
		InitConnexion();
		int N=CalculN();

		//URL des images de la BDD 
		URLimages=new ArrayList<String>();
		distjaime=new float[N];
		distjaimepas=new float[N];
		
	}
	
	/**permet la sélection des images proches des images choisies dans j'aime
	 * @param jaime
	 * @param jpas
	 */	
	public void RechercheJaime(){
		
		try {
			//on enregistre les informations utiles
			//des images sélectionnées
			
			//on enregistre les id des images sélectionnées
			int idSelect[]=new int[ListeUrl .size()];
			//on enregistre les id des descripteurs correspondant à ces images
			int descripteurs[][]=new int[ListeUrl .size()][2];
			
			String sql;
			ResultSet resultset;
			ResultSet resultset2;
			
			//pour chaque image choisie
			for(int i=0;i<ListeUrl .size();i++){
				sql = "SELECT id FROM indexation.META WHERE url='"+ListeUrl .get(i)+"'";
				resultset = connection.createStatement().executeQuery(sql);
				if(resultset .next()){
					//on enregistre les descripteur couleur et sobel
					idSelect [i]=resultset .getInt(1);
					sql = "SELECT id_descripteur FROM indexation.META_DESCRIPTEUR WHERE id_meta='"+resultset .getInt(1)+"'";
					resultset2 = connection.createStatement().executeQuery(sql);
					//couleur 
					resultset2.next();
					descripteurs[i][0]=resultset2.getInt(1);
					//sobel
					resultset2.next();
					descripteurs[i][1]=resultset2.getInt(1);
					
				}
					
			}
			
			float distancemoyenne;
			
			int couleur,sobel;
			float sommecouleur,sommesobel,mincouleur,minsobel;
			//float moyennecouleur,moyennesobel;
			
			//int indice=URLimages.size();
			int indice=0;
			
			
			//Pour chaque image de la BDD
			sql = "SELECT id,url FROM indexation.META ";
			resultset = connection.createStatement().executeQuery(sql);
			boolean test=false;
			while(resultset .next()){
				test=false;
	
				//si l'image est l'un de celles choisies on met la distance à 0
				for(int i=0;i<idSelect.length;i++)
				{
					if(idSelect[i]==resultset.getInt(1))
						test=true;
				}
				
				if(test){
					URLimages .add(resultset.getString(2));
					distjaime[indice]=0;
					indice++;
				}
				
				//sinon on fait le test
				else{
					
					//on récupère les id de ses descripteurs
					sql = "SELECT id_descripteur FROM indexation.META_DESCRIPTEUR WHERE id_meta='"+resultset .getInt(1)+"'";
					resultset2 = connection.createStatement().executeQuery(sql);
					resultset2.next();
					couleur=resultset2.getInt(1);
					resultset2.next();
					sobel=resultset2.getInt(1);

					//puis on les compare
					//à ceux des images choisies
					sommecouleur=0;
					sommesobel=0;
					mincouleur=0;
					minsobel=0;
					for(int i=0;i<idSelect.length;i++){
						//distance entre les couleurs
						sql = "SELECT value FROM indexation.DISTANCE WHERE (id_desc1='"+descripteurs[i][0]+"' AND id_desc2='"+couleur+"')";
						resultset2 = connection.createStatement().executeQuery(sql);
						resultset2.next();
						sommecouleur+=resultset2.getFloat(1);
						if(mincouleur==0)
							mincouleur=resultset2.getFloat(1);
						else if(mincouleur>resultset2.getFloat(1))
							mincouleur=resultset2.getFloat(1);
					
						//distance entre les sobel
						sql = "SELECT value FROM indexation.DISTANCE WHERE (id_desc1='"+descripteurs[i][1]+"' AND id_desc2='"+sobel+"')";
						resultset2 = connection.createStatement().executeQuery(sql);
						resultset2.next();
						if(minsobel==0)
							minsobel=resultset2.getFloat(1);
						else if(minsobel>resultset2.getFloat(1))
							minsobel=resultset2.getFloat(1);
					}
					
					//si les distance couleur sont petite ont ajoute l'image
					if((mincouleur)<(0.35))
					{
						distancemoyenne=(sommecouleur+sommesobel)/(2*idSelect.length);
						URLimages .add(resultset.getString(2));
						distjaime[indice]=distancemoyenne;
						indice++;	
					}
					//si les distance sobel sont petite ont ajoute l'image
					else if(minsobel<350){
						distancemoyenne=(sommecouleur+sommesobel)/(2*idSelect.length);
						URLimages .add(resultset.getString(2));
						distjaime[indice]=distancemoyenne;
						indice++;
					}	
				}
			}
			
			//trie();
			
			
		} catch (SQLException e) {
			e.printStackTrace();
		}
	
}
	
	
	/**Si l'un des images sélectionnées est trop proche
	 * d'une image j'aime pas, on la supprime de la sélection
	 */
	public void RechercheJaimePas(){
		try{
			//on enregistre les id des images jaime pas
			int idSelect[]=new int[jaimepas .size()];
			//on enregistre les id des descripteurs correspondant à ces images
			int descripteurs[][]=new int[jaimepas .size()][2];
			
			
			String sql;
			ResultSet resultset;
			ResultSet resultset2;
			
			//pour chaque image choisie
			for(int i=0;i<jaimepas .size();i++){
				sql = "SELECT id FROM indexation.META WHERE url='"+jaimepas .get(i)+"'";
				resultset = connection.createStatement().executeQuery(sql);
				if(resultset .next()){
					//on enregistre les descripteur couleur et sobel
					idSelect [i]=resultset .getInt(1);
					sql = "SELECT id_descripteur FROM indexation.META_DESCRIPTEUR WHERE id_meta='"+resultset .getInt(1)+"'";
					resultset2 = connection.createStatement().executeQuery(sql);
					//couleur 
					resultset2.next();
					descripteurs[i][0]=resultset2.getInt(1);
					//sobel
					resultset2.next();
					descripteurs[i][1]=resultset2.getInt(1);
					
				}	
			}
	
			//Pour chaque image de la BDD
			sql = "SELECT id,url FROM indexation.META ";
			resultset = connection.createStatement().executeQuery(sql);
			boolean test=false;
			float mincouleur,minsobel;
			int couleur;
			int sobel;
			while(resultset .next()){
				test=false;
				
				for(int i=0;i<idSelect.length;i++)
				{
					if(idSelect[i]==resultset.getInt(1))
						test=true;
				}
				
				//si la liste contient une url sélectionnée dans j'aime pas on la supprime
				if(test){	
					if(URLimages.contains(resultset.getString(2)))
						URLimages.remove(resultset.getString(2));
				}
				else{
					//on récupère les id de ses descripteurs
					sql = "SELECT id_descripteur FROM indexation.META_DESCRIPTEUR WHERE id_meta='"+resultset .getInt(1)+"'";
					resultset2 = connection.createStatement().executeQuery(sql);
					resultset2.next();
					couleur=resultset2.getInt(1);
					resultset2.next();
					sobel=resultset2.getInt(1);
					
					//puis on les compare
					//à ceux des images j'aime pas
					minsobel=0;
					mincouleur=0;
					for(int i=0;i<idSelect.length;i++){
					
						//distance entre les couleurs
						sql = "SELECT value FROM indexation.DISTANCE WHERE (id_desc1='"+descripteurs[i][0]+"' AND id_desc2='"+couleur+"')";
						resultset2 = connection.createStatement().executeQuery(sql);
						resultset2.next();
						if(mincouleur==0)
							mincouleur=resultset2.getFloat(1);
						else if(mincouleur>resultset2.getFloat(1));
							mincouleur=resultset2.getFloat(1);
					
						//distance entre les sobel
						sql = "SELECT value FROM indexation.DISTANCE WHERE (id_desc1='"+descripteurs[i][1]+"' AND id_desc2='"+sobel+"')";
						resultset2 = connection.createStatement().executeQuery(sql);
						resultset2.next();
						if(minsobel==0)
							minsobel=resultset2.getFloat(1);
						else if(minsobel>resultset2.getFloat(1));
							minsobel=resultset2.getFloat(1);
					}
					
					if(mincouleur<(0.30))
					{
						if(URLimages.contains(resultset.getString(2)))
						{
							//si elle n'a pas été sélectionnée dans j'aime on peut la supprimer
							if(!ListeUrl.contains(resultset.getString(2)))
								URLimages .remove(resultset.getString(2));
						}
						
					}
					
					if(minsobel<300){
						if(URLimages.contains(resultset.getString(2)))
						{
							//si elle n'a pas été sélectionnée dans j'aime on peut la supprimer
							if(!ListeUrl.contains(resultset.getString(2)))
								URLimages .remove(resultset.getString(2));
						}
					}
				}
			}			
		}
		catch(Exception e){System.out.println(e);}
	}
	
	/**Permet de rechercher les images en fonction de leurs distances 
	 * avec les images j'aime et j'aime pas
	 */
	public void RechercheParDistance(){
		int connex=InitConnexion();
		if(connex==1){
			
			RechercheJaime();
			RechercheMots(1);	//première étape 
			trie();
			if(jaimepas.size()!=0)
				RechercheJaimePas();
			RechercheMots(2);	//deuxième étape
			try {
				connection.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}
	
	/**Recherche les images ayant des mots clés communs
	 * avec les images choisies dans j'aime
	 */
	public void RechercheMots(int val){
		
		//si val=1 on n'a pas encore sélectionné d'image
		//on cherche les images ayant au moins 60% de mots en communs
		//on met une distance à 0,1 pour être juste après les images sélectionnées dans j'aime
		String sql;
		ResultSet resultset;
		ArrayList<String> motsJaime=new ArrayList<String>();
		
		//liste des mots clés des images j'aime
		motsJaime=MotsJaime();
		int nombreMotsJaime=motsJaime.size();
		int motImage;

		//début de la recherche: 60%
		if(val==1){
			double pourcentage60;
			int indice=URLimages.size();
			
			try{
			
				pourcentage60=(float)nombreMotsJaime*0.6;
				
				//on sélectionne les images ayant au moins 60% de mots communs
				sql = "SELECT id,url FROM indexation.META ";
				resultset = connection.createStatement().executeQuery(sql);
				while(resultset.next()){
					if(!ListeUrl.contains(resultset.getString(2))){
						motImage=nbCorresp(resultset.getInt(1), motsJaime);
						
						if(motImage>pourcentage60){
							URLimages .add(resultset.getString(2));
							distjaime[indice]=(float) 0.1;
							indice++;					
						}
					}
				}
				
			}
			
			catch(Exception e){}			
		}
		
		//fin de la recherche:30%
		else{
			
			double pourcentage30;

			try{
			
				pourcentage30=nombreMotsJaime*0.3;
				
				//on sélectionne les images ayant au moins 30% de mots communs
				sql = "SELECT id,url FROM indexation.META ";
				resultset = connection.createStatement().executeQuery(sql);
				while(resultset.next()){
					if(!ListeUrl.contains(resultset.getString(2))){
						motImage=nbCorresp(resultset.getInt(1), motsJaime);
						
						//si les images ne sont pas déjà dans la liste
						if(motImage>pourcentage30){
							if(!URLimages.contains(resultset.getString(2)))
								URLimages .add(resultset.getString(2));
												
						}
					}
				}
				
				
				
			}
			catch(Exception e){}	
			
		}
	}

	public int nbCorresp(int id,ArrayList<String> motsJaime){
		int nb=0;
		
		
		String sql;
		ResultSet resultset;
		ResultSet resultset2;
		
		try{

			sql = "SELECT id_keyword FROM indexation.META_KEYWORD WHERE id_meta='"+id+"'";
			resultset = connection.createStatement().executeQuery(sql);
			while(resultset .next()){
				sql = "SELECT racine FROM indexation.KEYWORD WHERE id='"+resultset .getInt(1)+"'";
				resultset2 = connection.createStatement().executeQuery(sql);
				while(resultset2 .next()){
					if(motsJaime.contains(resultset2.getString(1)))
						nb++;
				}
			}
		
		}catch(Exception e){}
		
		
		return nb;
	}
	
	public ArrayList<String> MotsJaime(){
		String sql;
		ResultSet resultset;
		ResultSet resultset2;
		int idSelect[]=new int[ListeUrl .size()];
		ArrayList<String> motsJaime=new ArrayList<String>();
		
		try{
		//on garde les id des images choisies dans j'aime
		for(int i=0;i<ListeUrl .size();i++){
			sql = "SELECT id FROM indexation.META WHERE url='"+ListeUrl .get(i)+"'";
			resultset = connection.createStatement().executeQuery(sql);
			if(resultset .next())
				idSelect [i]=resultset .getInt(1);
			
		}
		
		//liste des mots clés des images j'aime
		for(int i=0;i<ListeUrl .size();i++){
			sql = "SELECT id_keyword FROM indexation.META_KEYWORD WHERE id_meta='"+idSelect [i]+"'";
			resultset = connection.createStatement().executeQuery(sql);
			while(resultset .next()){
				sql = "SELECT racine FROM indexation.KEYWORD WHERE id='"+resultset .getInt(1)+"'";
				resultset2 = connection.createStatement().executeQuery(sql);
				while(resultset2 .next()){
					motsJaime.add(resultset2.getString(1));
				}
			}
		}
		}catch(Exception e){}
		return motsJaime;
	}
	
	
	/**Trie des images sélectionnées par j'aime
	 */
	public void trie(){
		
		ArrayList<String> temp=new ArrayList<String>();

		int indexMin;
		while(URLimages.size()!=0){
			
			indexMin=0;
			
			//on recherche la plus petite distance
			for(int i=1;i<URLimages.size();i++){
				
				if(distjaime[i]<distjaime[indexMin])
					indexMin=i;
			}
			//on ajoute l'image la plus petite dans la liste finale
			temp.add(URLimages.get(indexMin));
			
			//on la supprime de la liste de recherche
			URLimages.remove(indexMin);
			for(int i=indexMin;i<URLimages.size();i++)
				distjaime[i]=distjaime[i+1];
			
		}
		
		
		URLimages=temp;
		
		
		
	}
	
	/**Initialisation de la connexion
	 */
	public int InitConnexion()
	{
		//Connexion  la bdd
				ConnexionBDD connexionBDD = new ConnexionBDD();
				
				
				try {
					connection = connexionBDD.initConnection();

					/*
					 * Test d'interaction avec la base
					 */
					if (!connection.isClosed()) {
						System.out.println("Connexion reussie");
						return 1;
						//connection.createStatement().close();
					} 
					else{
						System.out.println("Echec de la connexion");
						return 0;
					}
					//connection.close();
					
				} catch (Exception e) {
					System.out.println("erreur connexion: "+e);
					return 0;}
	}

/**Calcul du nombre d'images dans la BDD
 * @return
 */
	public int CalculN(){
		int N=0;
		String sql = "SELECT id FROM indexation.META ";
		ResultSet resultset;
		try {
			System.out.println(sql);
			resultset = connection.createStatement().executeQuery(sql);
			while(resultset.next()){
				N++;
			}
		}catch(Exception e){}
	
		return N;
	}
	
	public ArrayList<String> getArray_url() {
		return URLimages;
	}
}
